package com.school.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Token 工具类
 * 使用简单的加密算法生成token
 */
@Slf4j
public class TokenUtils {
    
    /**
     * Token密钥
     */
    private static final String SECRET_KEY = "dormitory-management-system-secret-key-2024";
    
    /**
     * Token有效期（毫秒），默认7天
     */
    private static final long EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000L;
    
    /**
     * 生成Token
     * @param userId 用户ID
     * @param username 用户名
     * @return token字符串
     */
    public static String generateToken(Long userId, String username) {
        try {
            // 当前时间
            long currentTime = System.currentTimeMillis();
            // 过期时间
            long expireTime = currentTime + EXPIRE_TIME;
            
            // 构建token数据
            String data = String.format("%s:%s:%s:%s", 
                userId, 
                username, 
                currentTime, 
                expireTime
            );
            
            // 使用MD5加密
            String sign = SecureUtil.md5(data + SECRET_KEY);
            
            // 组合token: userId-username-currentTime-expireTime-sign
            String token = String.format("%s-%s-%s-%s-%s", 
                userId, 
                username, 
                currentTime, 
                expireTime, 
                sign
            );
            
            log.info("生成Token成功: userId={}, username={}, expireTime={}", 
                userId, username, DateUtil.formatDateTime(new Date(expireTime)));
            
            return token;
        } catch (Exception e) {
            log.error("生成Token失败", e);
            return null;
        }
    }
    
    /**
     * 验证Token是否有效
     * @param token token字符串
     * @return 是否有效
     */
    public static boolean validateToken(String token) {
        if (StrUtil.isBlank(token)) {
            return false;
        }
        
        try {
            String[] parts = token.split("-");
            if (parts.length != 5) {
                return false;
            }
            
            String userId = parts[0];
            String username = parts[1];
            String currentTime = parts[2];
            String expireTime = parts[3];
            String sign = parts[4];
            
            // 检查是否过期
            long expireTimeLong = Long.parseLong(expireTime);
            if (System.currentTimeMillis() > expireTimeLong) {
                log.warn("Token已过期: token={}", token);
                return false;
            }
            
            // 验证签名
            String data = String.format("%s:%s:%s:%s", 
                userId, username, currentTime, expireTime);
            String expectedSign = SecureUtil.md5(data + SECRET_KEY);
            
            if (!expectedSign.equals(sign)) {
                log.warn("Token签名验证失败: token={}", token);
                return false;
            }
            
            return true;
        } catch (Exception e) {
            log.error("验证Token失败", e);
            return false;
        }
    }
    
    /**
     * 从Token中解析用户信息
     * @param token token字符串
     * @return 用户信息Map，包含userId和username
     */
    public static Map<String, String> parseToken(String token) {
        Map<String, String> userInfo = new HashMap<>();
        
        if (StrUtil.isBlank(token)) {
            return userInfo;
        }
        
        try {
            String[] parts = token.split("-");
            if (parts.length != 5) {
                return userInfo;
            }
            
            userInfo.put("userId", parts[0]);
            userInfo.put("username", parts[1]);
            
            return userInfo;
        } catch (Exception e) {
            log.error("解析Token失败", e);
            return userInfo;
        }
    }
    
    /**
     * 获取Token过期时间
     * @param token token字符串
     * @return 过期时间（Date对象），解析失败返回null
     */
    public static Date getExpireTime(String token) {
        if (StrUtil.isBlank(token)) {
            return null;
        }
        
        try {
            String[] parts = token.split("-");
            if (parts.length != 5) {
                return null;
            }
            
            long expireTime = Long.parseLong(parts[3]);
            return new Date(expireTime);
        } catch (Exception e) {
            log.error("获取Token过期时间失败", e);
            return null;
        }
    }
    
    /**
     * 刷新Token（延长有效期）
     * @param oldToken 旧token
     * @return 新token
     */
    public static String refreshToken(String oldToken) {
        if (!validateToken(oldToken)) {
            return null;
        }
        
        try {
            Map<String, String> userInfo = parseToken(oldToken);
            String userId = userInfo.get("userId");
            String username = userInfo.get("username");
            
            return generateToken(Long.parseLong(userId), username);
        } catch (Exception e) {
            log.error("刷新Token失败", e);
            return null;
        }
    }
}

